home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-25 | 45.6 KB | 1,682 lines | [TEXT/MPS ] |
- {$P}
- {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]}
- { UMacApp.TWindow.p }
- { Copyright © 1987-1990 by Apple Computer Inc. All rights reserved. }
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAClose}
-
- PROCEDURE TCloseWindowCommand.DoIt;
-
- BEGIN
- IF fView <> NIL THEN
- TWindow(fView).CloseByUser;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MASelCommand}
-
- PROCEDURE TCloseWindowCommand.ICloseWindowCommand(itsCmdNumber: CmdNumber;
- itsWindow: TWindow);
-
- BEGIN
- INoChangesCommand(itsCmdNumber, NIL, itsWindow, NIL);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAFields}
-
- PROCEDURE TCloseWindowCommand.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: integer)); OVERRIDE;
-
- BEGIN
- DoToField('TCloseWindowCommand', NIL, bClass);
-
- INHERITED Fields(DoToField);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAOpen}
-
- PROCEDURE TWindow.IWindow(itsDocument: TDocument;
- itsWMgrWindow: WindowPtr;
- canResize, canClose, disposeOnFree: BOOLEAN);
-
- VAR
- preDocname: integer;
- constTitle: integer;
- aString: Str255;
- fi: FailInfo;
- p: Point;
- vp: VPoint;
-
- PROCEDURE HandleFailure(error: OSErr;
- message: LONGINT);
-
- BEGIN
- Free;
- END;
-
- FUNCTION GetSetVPt(v, h: VCoordinate): VPoint;
-
- VAR
- aVPt: VPoint;
-
- BEGIN
- aVPt.v := v;
- aVPt.h := h;
- GetSetVPt := aVPt;
- END;
-
- BEGIN
- { set up fields necessary to free myself }
- fWMgrWindow := itsWMgrWindow;
- fFreeOnClosing := FALSE;
- fDisposeOnFree := disposeOnFree;
-
- SetPort(GetGrafPort); { ??? Why is this necessary? }
- WITH fWMgrWindow^.portRect DO
- BEGIN
- p := topleft;
- LocalToGlobal(p);
- PtToVPt(p, vp);
- IView(itsDocument, NIL, vp, GetSetVPt(bottom - top, right - left), SizeVariable,
- SizeVariable);
- END;
-
- fProcID := GetWindowVariant(itsWMgrWindow);
- SetWRefcon(itsWMgrWindow, LONGINT(SELF));
-
- fAdapted := FALSE; { Set by AdaptToScreen }
- fHorzCentered := FALSE; { Set by Center }
- fVertCentered := FALSE; { Set by Center }
- fStaggered := FALSE; { Set by SimpleStagger }
- fForcedOnScreen := FALSE; { Set by ForceOnScreen }
-
- { We can't tell if any changing will be required so we just set these false here.
- If the developer sets them true then we respect them or if the developer calls the
- corresponding functions we set them. }
- fMustAdapt := FALSE;
- fMustHorzCenter := FALSE;
- fMustVertCenter := FALSE;
- fMustStagger := FALSE;
- fMustForceOnScreen := FALSE;
-
- fIsActive := FALSE;
- fIsResizable := canResize;
- fIsClosable := canClose;
- fTarget := SELF;
- fTargetID := fIdentifier;
- fClosesDocument := TRUE;
- fOpenInitially := TRUE;
- fIsModal := FALSE;
- fDoFirstClick := FALSE;
- fFloats := FALSE;
- IF BuildWindowRgns(BuildWindowRgns(kBuild)) THEN; { sets fContRgnInset & fContDifference }
-
- CatchFailures(fi, HandleFailure);
-
- fMoveBounds := gStdWMoveBounds;
- SetResizeLimits(gStdWSizeRect.topleft, gStdWSizeRect.botRight);
- GetTitle(aString);
- IF ParseTitleTemplate(aString, preDocname, constTitle) THEN
- SetWTitle(itsWMgrWindow, aString);
- fPreDocname := preDocname;
- fConstTitle := constTitle;
-
- InstallDocument(itsDocument);
-
- Success(fi);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAOpen}
-
- PROCEDURE TWindow.IRes(itsDocument: TDocument;
- itsSuperView: TView;
- VAR itsParams: Ptr);
-
- VAR
- bounds: Rect;
- aWMgrWindow: WindowPtr;
- preDocname: integer;
- constTitle: integer;
- aString: Str255;
- fi: FailInfo;
-
- PROCEDURE HandleFailure(error: OSErr;
- message: LONGINT);
-
- BEGIN
- Free;
- END;
-
- BEGIN
- { set up fields necessary to free myself }
- fWMgrWindow := NIL;
- fFreeOnClosing := FALSE;
- fDisposeOnFree := TRUE;
-
- INHERITED IRes(itsDocument, itsSuperView, itsParams);
-
- SetRect(bounds, fLocation.h, fLocation.v, fLocation.h + fSize.h, fLocation.v + fSize.v);
-
- WITH WindowTemplatePtr(itsParams)^ DO
- BEGIN
- CatchFailures(fi, HandleFailure);
-
- { ignore request for zoomDocProc if not 128K ROM, because
- the user might be running pre-3.0 System, which can't
- handle zoomDocProc }
- IF NOT qNeedsROM128K & NOT gConfiguration.hasROM128K THEN
- procID := BAND(procID, $FFF7);
-
- fProcID := procID;
-
- IF qNeedsColorQD | gConfiguration.hasColorQD THEN
- aWMgrWindow := WindowPtr(NewCWindow(NIL, bounds, title, FALSE, procID, Pointer( - 1),
- hasGoAway, ORD4(SELF)))
- ELSE
- aWMgrWindow := NewWindow(NIL, bounds, title, FALSE, procID, Pointer( - 1), hasGoAway,
- ORD4(SELF));
- fWMgrWindow := aWMgrWindow;
-
- fAdapted := FALSE; { Set by AdaptToScreen }
- fHorzCentered := FALSE; { Set by Center }
- fVertCentered := FALSE; { Set by Center }
- fStaggered := FALSE; { Set by SimpleStagger }
- fForcedOnScreen := FALSE; { Set by ForceOnScreen }
- fIsActive := FALSE;
- fIsResizable := resizable;
- fIsClosable := hasGoAway;
- fTarget := SELF;
- fTargetID := targetID;
- fIsModal := isModal;
- fDoFirstClick := doFirstClick;
- fFreeOnClosing := freeOnClosing;
- fDisposeOnFree := disposeOnFree;
- fClosesDocument := closesDocument;
- fOpenInitially := openInitially;
- fMoveBounds := gStdWMoveBounds;
- SetResizeLimits(gStdWSizeRect.topleft, gStdWSizeRect.botRight);
- fFloats := FALSE;
- IF BuildWindowRgns(BuildWindowRgns(kBuild)) THEN; { sets fContRgnInset & fContDifference }
-
- GetTitle(aString);
- IF ParseTitleTemplate(aString, preDocname, constTitle) THEN
- SetWTitle(aWMgrWindow, aString);
- fPreDocname := preDocname;
- fConstTitle := constTitle;
-
- InstallDocument(itsDocument);
-
- Success(fi);
-
- fMustAdapt := mustAdaptToScreen;
- fMustHorzCenter := horzCenter;
- fMustVertCenter := vertCenter;
- fMustStagger := stagger;
- fMustForceOnScreen := mustForceOnScreen;
-
- OffsetPtrWStr(itsParams, SIZEOF(WindowTemplate));
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWriteRes}
-
- PROCEDURE TWindow.WRes(theResource: ViewRsrcHandle;
- VAR itsParams: Ptr); OVERRIDE;
-
- VAR
- theTitle: Str255;
- wnPtr: WindowTemplatePtr;
-
- BEGIN
- INHERITED WRes(theResource, itsParams);
-
- GetTitle(theTitle);
-
- wnPtr := WindowTemplatePtr(ExpandPtrWStr(theResource, itsParams, SIZEOF(WindowTemplate),
- LENGTH(theTitle)));
-
- WITH wnPtr^ DO
- BEGIN
- procID := fProcID;
- hasGoAway := fIsClosable;
- resizable := fIsResizable;
- isModal := fIsModal;
- doFirstClick := fDoFirstClick;
- freeOnClosing := fFreeOnClosing;
- disposeOnFree := fDisposeOnFree;
- closesDocument := fClosesDocument;
- openInitially := fOpenInitially;
- mustAdaptToScreen := fMustAdapt;
- stagger := fMustStagger;
- mustForceOnScreen := fMustForceOnScreen;
- vertCenter := fMustVertCenter;
- horzCenter := fMustHorzCenter;
- targetID := fTargetID;
- CopyStr255(theTitle, PRStr(title));
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWriteRes}
-
- PROCEDURE TWindow.WriteRes(theResource: ViewRsrcHandle;
- VAR itsParams: Ptr); OVERRIDE;
-
- BEGIN
- gWResSignature := 'wind'; gWResType := 'TWindow';
- WRes(theResource, itsParams);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAClose}
-
- PROCEDURE TWindow.Free; OVERRIDE;
-
- VAR
- disposeOnFree: BOOLEAN;
- wmgrWindow: WindowPtr;
-
- BEGIN
- disposeOnFree := fDisposeOnFree;
- wmgrWindow := fWMgrWindow;
- fWMgrWindow := NIL; { ??? will this help? }
-
- IF fDocument <> NIL THEN
- fDocument.DeleteWindow(SELF)
- ELSE
- gApplication.DeleteFreeWindow(SELF);
-
- INHERITED Free;
-
- { ****** DON'T REFER TO ANY FIELDS OR METHODS OF SELF ****** }
-
- wmgrWindow := FreeIfWMgrWindow(wmgrWindow, disposeOnFree);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAActivate}
-
- PROCEDURE TWindow.Activate(entering: BOOLEAN);
-
- VAR
- different: BOOLEAN;
- aWindow: TWindow;
-
- BEGIN
- InvalidateFocus; { Must refocus to make sure thePort is set }
- different := entering <> fIsActive;
-
- IF different THEN
- BEGIN
- Update; { Logically the order is wrong, but it gives
- the correct visual effect. ??? Revisit? }
- INHERITED Activate(entering);
-
- IF entering THEN
- BEGIN
- aWindow := gApplication.GetActiveWindow;
- IF aWindow <> NIL THEN { So lost deactivate doesn't screw up
- gTarget }
- aWindow.Activate(FALSE);
- fIsActive := entering;
- gApplication.SetTarget(fTarget);
- END
- ELSE
- BEGIN
- fIsActive := entering;
- gApplication.SetTarget(gApplication);
- SetCursor(arrow); { ensure that the cursor is an arrow when
- MacApp loses control }
- END;
- END;
-
- IF fIsResizable & Focus & IsVisible THEN
- DrawResizeIcon;
-
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAOpen}
-
- PROCEDURE TWindow.AdaptToScreen;
-
- CONST
- stdHScreen = 512;
- stdVScreen = 342;
- stdScreen = $10000 * stdVScreen + stdHScreen;
-
- VAR
- diff: Point;
- windRect: Rect;
- newSize: Point;
- theLimits: Rect;
-
- BEGIN
- fAdapted := TRUE; { We adapted to the screen }
- { Compute difference between current screen and std Mac screen }
- diff := screenBits.bounds.botRight;
- SubPt(screenBits.bounds.topleft, diff);
- SubPt(Point(stdScreen), diff);
- GetGlobalBounds(windRect);
-
- { If screen is larger, enlarge the window. If the window is too large, shrink it }
- IF (LONGINT(diff) <> 0) | (windRect.bottom > screenBits.bounds.bottom) | { do an adjustment for
- larger screen }
- (windRect.right > screenBits.bounds.right) THEN
- BEGIN
- newSize := windRect.botRight;
- AddPt(diff, newSize); { the window adapted to the new screen size
- }
- theLimits := fResizeLimits;
- WITH theLimits DO
- BEGIN
- { Consider the location of the window, bound it by the resize limits }
- newSize.v := MinMax(top, newSize.v - windRect.top, bottom);
- newSize.h := MinMax(left, newSize.h - windRect.left, right);
- END;
-
- Resize(newSize.h, newSize.v, kInvalidate);
-
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- FUNCTION TWindow.AllowsMenuAccess: BOOLEAN;
-
- BEGIN
- { Default is to always allow menu access, even if modal }
- AllowsMenuAccess := TRUE;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MANonRes}
-
- FUNCTION GetAndLoadWDefProc(windowDefProc: Handle): Handle;
- { utility routine: given a windowDefProc, this routine returns its actual address and loads it }
-
- VAR
- wDefProc: Handle;
-
- BEGIN
- wDefProc := Handle(StripLong(windowDefProc));
- IF wDefProc^ = NIL THEN
- LoadResource(wDefProc);
- GetAndLoadWDefProc := wDefProc;
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- FUNCTION CallWDefProc(varCode: integer;
- theWindow: WindowPtr;
- message: integer;
- param: LONGINT;
- wDefProc: UNIV Handle): LONGINT;
- INLINE $205F, { MOVE.L (A7)+,A0 }
- $2050, { MOVE.L (A0),A0 }
- $4E90; { JSR (A0) }
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAOpen}
-
- PROCEDURE TWindow.Center(horizontally, vertically, forDialog: BOOLEAN);
-
- VAR
- windowSize: Point;
- screenSize: Point;
- contentSize: Point;
- bottomRightInset: Point;
- globalbounds, screenRect: Rect;
- rgnsWereBuilt: BOOLEAN;
-
- BEGIN
- fHorzCentered := horizontally;
- fVertCentered := vertically;
- IF (fWMgrWindow <> NIL) & (horizontally | vertically) THEN
- BEGIN
- IF GetMaxIntersectedDevice(screenRect) = NIL THEN; { don't care about result }
- WITH screenRect DO
- BEGIN
- screenSize.h := right - left;
- screenSize.v := bottom - top; { NOTE: GetMaxIntersectedDevice accounts for
- menubar so don't subtract gMbarHeight }
- END;
-
- WITH WindowPeek(fWMgrWindow)^ DO
- BEGIN
- rgnsWereBuilt := BuildWindowRgns(kBuild);
- WITH strucRgn^^.rgnBBox DO
- BEGIN
- windowSize.h := right - left;
- windowSize.v := bottom - top;
- END;
- IF BuildWindowRgns(rgnsWereBuilt) THEN; { discard result }
-
- GetGlobalBounds(globalbounds);
- WITH globalbounds DO
- BEGIN
- contentSize.h := right - left;
- contentSize.v := bottom - top;
- END;
-
- { The top-left content inset isn't enough; factor in the amount to the right of the }
- { content also. }
- bottomRightInset := windowSize;
- SubPt(contentSize, bottomRightInset);
- SubPt(fContRgnInset, bottomRightInset);
- {$PUSH} {$H-}
- SubPt(bottomRightInset, fContRgnInset);
- {$POP}
- END;
-
- WITH globalbounds DO
- BEGIN
- IF horizontally THEN
- left := (screenSize.h - contentSize.h + fContRgnInset.h) DIV 2;
- IF vertically THEN
- IF forDialog THEN
- { Put it in the top third of the screen }
- top := ((screenSize.v - contentSize.v + fContRgnInset.v) DIV 3) + 20
- ELSE
- top := ((screenSize.v - contentSize.v + fContRgnInset.v) DIV 2) + 20;
- END;
- Locate(globalbounds.left, globalbounds.top, kDontInvalidate);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAClose}
-
- PROCEDURE TWindow.Close; OVERRIDE;
-
- BEGIN
- INHERITED Close;
-
- Show(FALSE, kRedraw);
- Activate(FALSE); { ??? Is this necessary? }
-
- IF fFreeOnClosing THEN
- Free;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAClose}
-
- PROCEDURE TWindow.CloseByUser;
-
- BEGIN
- IF fDocument = NIL THEN { free window }
- Close
- ELSE
- fDocument.CloseView(SELF);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MASelCommand}
-
- FUNCTION TWindow.DoMenuCommand(aCmdNumber: CmdNumber): TCommand; OVERRIDE;
-
- VAR
- aCloseWindowCommand: TCloseWindowCommand;
- oldObjectPerm: BOOLEAN;
-
- BEGIN
- DoMenuCommand := NIL;
-
- CASE aCmdNumber OF
- cClose:
- BEGIN
- oldObjectPerm := AllocateObjectsFromPerm(FALSE); { Guarantee the allocation }
- New(aCloseWindowCommand);
- IF AllocateObjectsFromPerm(oldObjectPerm) THEN;
-
- FailNil(aCloseWindowCommand); { just in case }
- aCloseWindowCommand.ICloseWindowCommand(aCmdNumber, SELF);
- DoMenuCommand := aCloseWindowCommand;
- END;
- OTHERWISE
- DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
- END;
-
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- PROCEDURE TWindow.DoSetupMenus; OVERRIDE;
-
- BEGIN
- IF NOT fIsModal THEN { Don't enable menu/app commands if modal }
- BEGIN
- Enable(cClose, fIsClosable); { window objects take care of themselves! }
-
- INHERITED DoSetupMenus;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- PROCEDURE TWindow.DrawContents; OVERRIDE;
-
- VAR
- visRect: Rect;
- {$IFC qExperimentalAndUnsupported}
- fi: FailInfo;
- oldgEnableDoubleBuffering: Boolean;
- {$EndC}
-
- PROCEDURE HdlDrawContents(error: OSErr;
- message: LONGINT);
-
- BEGIN
- {$IFC qExperimentalAndUnsupported}
- gEnableDoubleBuffering := oldgEnableDoubleBuffering;
- {$EndC}
- END;
-
- PROCEDURE DoDrawContents;
-
- VAR
- visRect: Rect;
-
- BEGIN
- IF Focus THEN
- BEGIN
- { Ensure that the background is correct }
- GetVisibleRect(visRect);
- EraseRect(visRect);
-
- INHERITED DrawContents;
-
- { Draw the resize icon last so other views don't munch it.
- ??? Should the resize icon be a subview that is always drawn last?}
- IF fIsResizable THEN
- DrawResizeIcon;
- END;
- END;
-
- BEGIN
- {$IFC qExperimentalAndUnsupported}
- IF Focus & IsVisible THEN
- BEGIN
- IF gEnableDoubleBuffering & NOT (gPrinting | gDrawingPictScrap) THEN
- BEGIN
- oldgEnableDoubleBuffering := gEnableDoubleBuffering;
- gEnableDoubleBuffering := FALSE; { so subviews won't attempt to do off screen
- }
- CatchFailures(fi, HdlDrawContents);
- DoOffScreen(DoDrawContents);
- Success(fi);
- gEnableDoubleBuffering := oldgEnableDoubleBuffering;
- END
- ELSE
- DoDrawContents;
- END;
- {$ELSEC}
- DoDrawContents;
- {$EndC}
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- PROCEDURE TWindow.DrawResizeIcon;
-
- VAR
- r: Rect;
-
- BEGIN
- IF qDebug THEN
- AssumeFocused;
-
- GetQDExtent(r);
- r.left := r.right - kSBarSizeMinus1;
- r.top := r.bottom - kSBarSizeMinus1;
-
- {$IFC qDebug}
- UseTempRgn('TWindow.DrawResizeIcon');
- {$ENDC}
-
- GetClip(gTempRgn);
- ClipRect(r);
- PenNormal;
- DrawGrowIcon(fWMgrWindow);
- SetClip(gTempRgn);
-
- {$IFC qDebug}
- DoneWithTempRgn;
- {$ENDC}
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- FUNCTION TWindow.Focus: BOOLEAN; OVERRIDE;
-
- {$IFC qDebug OR qExperimentalAndUnsupported}
-
- VAR
- {$EndC}
- {$IFC qDebug}
- currentPort: GrafPtr;
- {$ENDC}
- {$IFC qExperimentalAndUnsupported}
- aFocusRec: FocusRec;
- {$EndC}
-
- BEGIN
- Focus := TRUE; { Hope for the best }
-
- IF IsFocused THEN
- BEGIN
- {$IFC qDebug}
- IF LONGINT(GetGrafPort^.portRect.topleft) <> 0 THEN
- ProgramBreak('TWindow.Focus: Origin is not (0,0)');
-
- GetPort(currentPort);
- IF currentPort <> GetGrafPort THEN
- BEGIN
- ProgramBreak('TWindow.Focus: Port is incorrect');
- Focus := FALSE
- END;
- {$ENDC}
- Exit(Focus);
- END;
-
- {$IFC qExperimentalAndUnsupported}
- IF fFocusRec.IsValid THEN
- BEGIN
- aFocusRec := fFocusRec;
- SetFocus(aFocusRec);
- Exit(Focus);
- END;
- {$EndC}
-
- IF (gDrawingPictScrapView = SELF) | ((gCurrPrintHandler <> NIL) & (gCurrPrintHandler.fView =
- SELF)) THEN
- BEGIN
- { GrafPort has been supplied }
- gFocusedView := SELF;
- END
-
- ELSE IF fWMgrWindow <> NIL THEN
- BEGIN
- SetPort(GetGrafPort);
- SetOrigin(0, 0);
- gLongOffset := gZeroVPt;
- SetClip(thePort^.visRgn);
- gFocusedView := SELF;
-
- {$IFC qExperimentalAndUnsupported}
- aFocusRec.clip := fFocusRec.clip;
- GetFocus(aFocusRec);
- fFocusRec := aFocusRec;
- {$EndC}
- END
- ELSE
- BEGIN
- { If we get this far, then we can't focus }
- ClipRect(gZeroRect);
- InvalidateFocus;
- Focus := FALSE;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- FUNCTION TWindow.FocusOnSuperView: BOOLEAN; OVERRIDE;
-
- BEGIN
- FocusOnSuperView := FALSE;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAOpen}
-
- PROCEDURE TWindow.ForceOnScreen;
-
- { ForceOnScreen guarantees that some minimal drag area is accessible to the user, to be dragged
- to the desired location. }
-
- CONST
- kMinDragArea = 4; { ??? should this be settable? }
-
- VAR
- global: Rect;
- deltaH: integer;
- deltaV: integer;
- aTempRgn: RgnHandle;
- rgnsWereBuilt: BOOLEAN;
-
- PROCEDURE AdjustGlobalBounds(VAR boundsToAdjust: Rect);
- { assume "boundsToAdjust" is set to the window bounds in global coordinates }
-
- VAR
- visScreenRect: Rect;
-
- BEGIN
- { since we don't _really_ know what the drag rgn is, we'll assume that moving the topleft
- pt of the window on screen is sufficient to make it draggable, so calculate the deltas
- necessary to move the topleft pt into visible screen rect }
-
- IF GetMaxIntersectedDevice(visScreenRect) = NIL THEN; { NOTE: uses gTempRgn }
- InsetRect(visScreenRect, kMinDragArea, kMinDragArea);
- WITH visScreenRect DO
- BEGIN
- IF boundsToAdjust.top < top THEN
- deltaV := top - boundsToAdjust.top + fContRgnInset.v
- ELSE IF boundsToAdjust.top > bottom THEN
- deltaV := bottom - boundsToAdjust.top - fContRgnInset.v;
-
- IF boundsToAdjust.left < left THEN
- deltaH := left - boundsToAdjust.left + fContRgnInset.h
- ELSE IF boundsToAdjust.left > right THEN
- deltaH := right - boundsToAdjust.right - fContRgnInset.h;
- END;
- END;
-
- BEGIN
- fForcedOnScreen := TRUE;
-
- deltaH := 0;
- deltaV := 0;
-
- { On many systems (including Color QD & the Radius FPD), it's possible to have a
- non-rectangular desktop. Try to be nice to people who saved windows
- on secondary screens. GrayRgn is the true indicator of the shape
- of the desktop--screenBits.bounds is the size of the screen with the
- menu bar on it. }
-
- {$IFC qDebug}
- UseTempRgn('ForceOnScreen');
- {$ENDC}
-
- rgnsWereBuilt := BuildWindowRgns(kBuild);
- WITH WindowPeek(fWMgrWindow)^ DO
- BEGIN
- DiffRgn(strucRgn, contRgn, gTempRgn); { strucRgn less contRgn ≈≈ drag rgn }
- IF EmptyRgn(gTempRgn) THEN
- CopyRgn(strucRgn, gTempRgn); { at least get the strucRgn }
- END; { WITH WindowPeek(fWMgrWindow)^ }
- IF BuildWindowRgns(rgnsWereBuilt) THEN; { discard result }
-
- { get the desktop rgn, inset by a minimal drag area }
- aTempRgn := MakeNewRgn;
- CopyRgn(GetGrayRgn, aTempRgn); { aTempRgn := desktop rgn }
- InsetRgn(aTempRgn, kMinDragArea, kMinDragArea); { inset aTempRgn }
- SectRgn(gTempRgn, aTempRgn, aTempRgn); { do drag rgn & desktop rgn instersect ? }
- {$IFC qDebug}
- DoneWithTempRgn; { (AdjustGlobalBounds needs gTempRgn) }
- {$ENDC}
-
- GetGlobalBounds(global);
-
- IF EmptyRgn(aTempRgn) | NOT IsDraggable(aTempRgn^^.rgnBBox) THEN
- AdjustGlobalBounds(global); { no => adjust the window's global bounds }
- DisposeRgn(aTempRgn);
- OffsetRect(global, deltaH, deltaV);
- WITH global DO
- Locate(left, top, kDontInvalidate);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- PROCEDURE TWindow.GetGlobalBounds(VAR globalbounds: Rect);
-
- VAR
- savedPort: GrafPtr;
-
- BEGIN
- IF fWMgrWindow = NIL THEN
- globalbounds := gZeroRect { CSK 89.11.30 }
- ELSE
- BEGIN
- GetPort(savedPort);
- SetPort(GetGrafPort);
- globalbounds := GetGrafPort^.portRect;
- LocalToGlobal(globalbounds.topleft);
- LocalToGlobal(globalbounds.botRight);
- SetPort(savedPort);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MANonRes}
-
- FUNCTION TWindow.GetMaxIntersectedDevice(VAR screenRect: Rect): GDHandle;
-
- PROCEDURE CalcScreenRect;
-
- VAR
- aGDHandle, maxSectGD: GDHandle;
- globalStrucRect, aGDScreenRect: Rect;
- gdSectRect, dontCare: Rect;
- sectArea: LONGINT;
- maxSectArea: LONGINT;
- moveBounds: Rect;
- rgnsWereBuilt: BOOLEAN;
-
- BEGIN
- rgnsWereBuilt := BuildWindowRgns(kBuild); { sets fContRgnInset & fContDifference, and
- make sure contrgn and strucrgn are
- available }
- globalStrucRect := WindowPeek(fWMgrWindow)^.strucRgn^^.rgnBBox;
- IF BuildWindowRgns(rgnsWereBuilt) THEN; { discard result }
-
- moveBounds := fMoveBounds;
-
- aGDHandle := GetDeviceList;
- maxSectGD := GetMainDevice; { set as best choice default }
- maxSectArea := 0;
- REPEAT { calc which scrn intersects largest part of
- window }
- BEGIN
- aGDScreenRect := aGDHandle^^.gdRect;
- IF SectRect(aGDScreenRect, moveBounds, dontCare) & SectRect(globalStrucRect,
- aGDScreenRect,
- gdSectRect) THEN
- BEGIN
- WITH gdSectRect DO
- sectArea := IntMultiply(bottom - top, right - left);
- IF sectArea > maxSectArea THEN { do we have a new winner? }
- BEGIN
- maxSectArea := sectArea;
- maxSectGD := aGDHandle;
- END;
- END;
- aGDHandle := GetNextDevice(aGDHandle);
- END;
- UNTIL aGDHandle = NIL;
-
- IF maxSectGD <> GetMainDevice THEN
- screenRect := maxSectGD^^.gdRect
- ELSE
- BEGIN { Account for menu bar on the main screen.
- Don't just assume that its at the top of
- the screen! }
- {$IFC qDebug}
- UseTempRgn('TWindow.GetMaxIntersectedDevice');
- {$ENDC}
- RectRgn(gTempRgn, maxSectGD^^.gdRect); { main screen with menubar }
- SectRgn(gTempRgn, GetGrayRgn, gTempRgn); { GetGrayRgn = desktop rgn w/o menubar }
- screenRect := gTempRgn^^.rgnBBox; { => main screen w/o menubar }
- {$IFC qDebug}
- DoneWithTempRgn;
- {$ENDC}
- END;
- GetMaxIntersectedDevice := maxSectGD;
- END;
-
- BEGIN
- IF qNeedsColorQD | gConfiguration.hasColorQD THEN
- CalcScreenRect
- ELSE
- BEGIN { Account for menu bar on the main screen.
- Don't just assume that its at the top of
- the screen! }
- GetMaxIntersectedDevice := NIL; { we only have GDHandle in CQD world }
- {$IFC qDebug}
- UseTempRgn('TWindow.GetMaxIntersectedDevice');
- {$ENDC}
- RectRgn(gTempRgn, screenBits.bounds); { main screen with menubar }
- SectRgn(gTempRgn, GetGrayRgn, gTempRgn); { GetGrayRgn = desktop rgn w/o menubar }
- screenRect := gTempRgn^^.rgnBBox; { => main screen w/o menubar }
- {$IFC qDebug}
- DoneWithTempRgn;
- {$ENDC}
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAInspector}
-
- PROCEDURE TWindow.GetInspectorName(VAR inspectorName: Str255); OVERRIDE;
-
- BEGIN
- IF (fWMgrWindow <> NIL) & (NOT ODD(ORD4(fWMgrWindow))) THEN
- GetTitle(inspectorName);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- FUNCTION TWindow.GetGrafPort: GrafPtr; OVERRIDE;
-
- BEGIN
- IF gPrinting | gDrawingPictScrap THEN
- GetGrafPort := thePort {thePort assumed to be set by print handler}
- ELSE IF fWMgrWindow <> NIL THEN
- GetGrafPort := GrafPtr(fWMgrWindow)
- ELSE
- GetGrafPort := NIL;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- PROCEDURE TWindow.GetTitle(VAR theTitle: Str255);
-
- BEGIN
- GetWTitle(fWMgrWindow, theTitle);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- FUNCTION TWindow.GetWindow: TWindow; OVERRIDE;
-
- BEGIN
- GetWindow := SELF;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAClose}
-
- PROCEDURE TWindow.GoAwayByUser(globalMouse: Point);
-
- VAR
- aCloseWindowCommand: TCloseWindowCommand;
- oldObjectPerm: BOOLEAN;
-
- BEGIN
- IF fIsClosable & TrackGoAway(fWMgrWindow, globalMouse) THEN
- BEGIN
- oldObjectPerm := AllocateObjectsFromPerm(FALSE); { Guarantee the allocation }
- New(aCloseWindowCommand);
- IF AllocateObjectsFromPerm(oldObjectPerm) THEN;
-
- FailNil(aCloseWindowCommand); { just in case }
- aCloseWindowCommand.ICloseWindowCommand(cClose, SELF);
- PostCommand(aCloseWindowCommand);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MASelCommand}
-
- FUNCTION TWindow.HandleMouseDown(theMouse: VPoint;
- VAR info: EventInfo;
- VAR hysteresis: Point;
- VAR theCommand: TCommand): BOOLEAN; OVERRIDE;
-
- CONST
- systemEventMask = app4Mask; { !!! defined as OSEvt in the MPW 3.1
- interfaces }
-
- VAR
- wantsTheMouse: BOOLEAN;
- anEvent: EventRecord;
- aWMgrWindow: WindowPtr;
- whereMouseDown: integer;
-
- BEGIN
- theCommand := NIL;
- HandleMouseDown := TRUE;
-
- WITH info, thePEvent^ DO
- BEGIN
- whereMouseDown := FindWindow(where, aWMgrWindow);
-
- IF aWMgrWindow = fWMgrWindow THEN
- BEGIN
- CASE whereMouseDown OF
- inContent:
- BEGIN
- wantsTheMouse := TRUE;
- IF gApplication.GetActiveWindow <> SELF THEN
- BEGIN
- Select;
- IF fDoFirstClick THEN
- { Make sure this window is activated and updated }
- gApplication.UpdateAllWindows
- ELSE
- wantsTheMouse := FALSE;
- END;
-
- IF wantsTheMouse THEN
- HandleMouseDown := INHERITED HandleMouseDown(theMouse, info, hysteresis,
- theCommand)
- ELSE
- HandleMouseDown := FALSE;
- END;
-
- inDrag:
- MoveByUser(where);
-
- inGrow:
- ResizeByUser(where);
-
- inGoAway:
- GoAwayByUser(where);
-
- inZoomIn, inZoomOut:
- ZoomByUser(where, whereMouseDown);
-
- inDesk: ;
-
- END;
- END
- ELSE IF qDebug THEN
- ProgramBreak(
- 'in TWindow.HandleMouseDown: passed an event that didn''t belong to the window'
- );
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- FUNCTION TWindow.HasPendingUpdate: BOOLEAN;
-
- BEGIN
- HasPendingUpdate := NOT EmptyRgn(WindowPeek(fWMgrWindow)^.updateRgn);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAOpen}
-
- PROCEDURE TWindow.InstallDocument(itsDocument: TDocument);
-
- VAR
- aString: Str255;
-
- BEGIN
- fDocument := itsDocument;
- IF itsDocument <> NIL THEN
- BEGIN
- gApplication.DeleteFreeWindow(SELF); { Just in case… }
- itsDocument.AddWindow(SELF);
- aString := itsDocument.fTitle^^; { SetTitleForDoc may move memory }
- IF aString <> '' THEN { not an untitled document }
- SetTitleForDoc(aString);
- fNextHandler := itsDocument;
- END
- ELSE
- BEGIN
- gApplication.AddFreeWindow(SELF);
- fNextHandler := gApplication;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- FUNCTION PushLong(h, v: integer): LONGINT;
- { This can be used to push a longint given a point. PushLong(aPt.h,aPt.v); }
- INLINE $2E9F; { MOVE.L (A7)+,(A7) }
-
- {--------------------------------------------------------------------------------------------------}
- {$S MANonRes}
-
- FUNCTION TWindow.IsDraggable(whichRect: Rect): BOOLEAN;
- { Returns TRUE if any of the corner points of whichRect are draggable. }
-
- VAR
- wDefProc: Handle;
- variant: integer;
- dontCare: LONGINT;
- saveState: SignedByte;
- rgnsWereBuilt: BOOLEAN;
-
- BEGIN
- IsDraggable := TRUE;
- rgnsWereBuilt := BuildWindowRgns(kBuild); { regions needed for hit testing }
- wDefProc := GetAndLoadWDefProc(WindowPeek(fWMgrWindow)^.windowDefProc);
- variant := GetWindowVariant(fWMgrWindow);
- saveState := GetHandleBits(wDefProc);
- LockHandleHigh(wDefProc);
-
- WITH whichRect DO { is any corner pt in the drag region? }
- IF (CallWDefProc(variant, fWMgrWindow, wHit, PushLong(left, top), wDefProc) <> wInDrag) &
- (CallWDefProc(variant, fWMgrWindow, wHit, PushLong(right, bottom), wDefProc) <>
- wInDrag) & (CallWDefProc(variant, fWMgrWindow, wHit, PushLong(left, bottom),
- wDefProc) <> wInDrag) & (CallWDefProc(variant, fWMgrWindow, wHit, PushLong(right, top),
- wDefProc) <> wInDrag) THEN
- IsDraggable := FALSE; { …no, so window _isn't_ draggable }
-
- SetHandleBits(wDefProc, saveState);
- IF BuildWindowRgns(rgnsWereBuilt) THEN; { discard result }
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MANonRes}
-
- FUNCTION TWindow.BuildWindowRgns(build: BOOLEAN): BOOLEAN;
- { Calculate window size including structure region (i.e. title bar). To do this
- we need to force the window to compute its structure region by calling its defproc,
- if the window isn't shown.
- IF build is FALSE, set the regions back to empty regions, so as not to confuse the
- window manager.
- Return the previous state of the regions. }
-
- VAR
- dontCare: LONGINT;
- wDefProc: Handle;
- topLeftInset, contDifference: Point;
- globalStrucRect, globalContRect: Rect;
- saveState: SignedByte;
-
- BEGIN
- WITH WindowPeek(fWMgrWindow)^ DO
- BEGIN
- { The regions are considered to be built if either:
- a) the window is shown; or
- b) the structure rgn is not empty. }
- IF IsShown | NOT EmptyRgn(strucRgn) THEN
- BEGIN
- BuildWindowRgns := kBuild;
- IF (build <> kBuild) & NOT IsShown THEN
- BEGIN
- SetEmptyRgn(strucRgn);
- SetEmptyRgn(contRgn);
- END;
- END
- ELSE
- BEGIN
- BuildWindowRgns := NOT kBuild;
- IF (build = kBuild) THEN
- BEGIN
- wDefProc := GetAndLoadWDefProc(windowDefProc);
- saveState := GetHandleBits(wDefProc);
- LockHandleHigh(wDefProc);
- dontCare := CallWDefProc(GetWindowVariant(fWMgrWindow), fWMgrWindow, wCalcRgns, 0,
- wDefProc);
- SetHandleBits(wDefProc, saveState);
-
- { Calculate offset from top-left of window structure to top-left of window content}
- topLeftInset := contRgn^^.rgnBBox.topleft;
- SubPt(strucRgn^^.rgnBBox.topleft, topLeftInset);
- fContRgnInset := topLeftInset;
- globalStrucRect := WindowPeek(fWMgrWindow)^.strucRgn^^.rgnBBox;
- globalContRect := WindowPeek(fWMgrWindow)^.contRgn^^.rgnBBox;
- contDifference.v := (globalStrucRect.bottom - globalStrucRect.top) -
- (globalContRect.bottom - globalContRect.top);
- contDifference.h := (globalStrucRect.right - globalStrucRect.left) -
- (globalContRect.right - globalContRect.left);
- fContDifference := contDifference;
- END;
- END;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- FUNCTION TWindow.IsShown: BOOLEAN; OVERRIDE;
-
- BEGIN
- IF fWMgrWindow <> NIL THEN
- IsShown := Ord(WindowPeek(fWMgrWindow)^.visible) <> 0
- ELSE
- IsShown := FALSE;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- PROCEDURE TWindow.Locate(h, v: VCoordinate;
- invalidate: BOOLEAN); OVERRIDE;
- VAR
- currLoc: Point;
-
- BEGIN
-
- INHERITED Locate(h, v, invalidate);
-
- IF fWMgrWindow <> NIL THEN
- BEGIN
- currLoc := fWMgrWindow^.portRect.topleft;
- LocalToGlobal(currLoc);
- IF (h <> currLoc.h) | (v <> currLoc.v) THEN
- MoveWindow(fWMgrWindow, h, v, FALSE); { ??? should offset by fContRgnInset.v }
- END;
- IF (fIsActive | fDoFirstClick) & IsShown THEN
- gApplication.InvalidateCursorRgn; {??? should this be a view method? }
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- PROCEDURE TWindow.Select;
-
- BEGIN
- gApplication.SelectWMgrWindow(fWMgrWindow);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- PROCEDURE TWindow.MoveByUser(globalMouse: Point);
-
- VAR
- boundsRect: Rect;
- currLoc: Point;
-
- BEGIN
- boundsRect := fMoveBounds;
- DragWindow(fWMgrWindow, globalMouse, boundsRect);
- gLastUpTime := TickCount; { needed for double clicking the title bar,
- because DragWindow eats the mouseUpEvent }
-
- { Don't forget to tell the window object }
- currLoc := fWMgrWindow^.portRect.topLeft;
- LocalToGlobal(currLoc);
- Locate(currLoc.h, currLoc.v, kDontInvalidate);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAOpen}
-
- PROCEDURE TWindow.Open; OVERRIDE;
-
- BEGIN
- IF NOT IsShown THEN
- BEGIN
- { Keep us matching the window since we are parallel structures }
- WITH fWMgrWindow^.portRect DO
- Resize(right - left, bottom - top, kDontInvalidate); { Be sure all views are sized right }
-
- AdjustSize; { Give non-template views a shot at
- correcting for sizedeterminers }
-
- IF fMustAdapt & NOT fAdapted THEN
- AdaptToScreen;
- IF (fMustHorzCenter & NOT fHorzCentered) | (fMustVertCenter & NOT fVertCentered) THEN
- Center(fMustHorzCenter, fMustVertCenter, fIsModal);
- IF fMustStagger & NOT fStaggered THEN
- BEGIN
- { If both staggering and forcing on screen are specified then we must ensure
- that the window is forced on screen FIRST so that the staggering will occur
- in a visible (and usable) location. BUT, after staggering we must STILL ensure
- that the window is forced on screen so, we reset the forced flag so that
- forcing will occur on schedule later. }
- IF fMustForceOnScreen & NOT fForcedOnScreen THEN
- BEGIN
- ForceOnScreen;
- fForcedOnScreen := FALSE; { Make sure we can be forced again }
- END;
- SimpleStagger(kStdStaggerAmount, kStdStaggerAmount, gStdStaggerCount);
- END;
- IF fMustForceOnScreen & NOT fForcedOnScreen THEN
- ForceOnScreen;
-
- Show(TRUE, kRedraw); { Make me visible }
-
- END;
- INHERITED Open; { Tell subviews to open in case they care }
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MANonRes}
-
- PROCEDURE TWindow.Resize(width, height: VCoordinate;
- invalidate: BOOLEAN); OVERRIDE;
-
- VAR
- r: Rect;
-
- BEGIN
- IF (width <> fSize.h) | (height <> fSize.v) THEN
- BEGIN
- SizeWindow(fWMgrWindow, width, height, invalidate);
- InvalidateFocus;
-
- IF fIsResizable & invalidate & Focus THEN
- BEGIN
-
- SetRect(r, - kSBarSizeMinus1, - kSBarSizeMinus1, 0, 0);
-
- OffsetRect(r, fSize.h, fSize.v);
- InvalidRect(r);
-
- OffsetRect(r, width - fSize.h, height - fSize.v);
- InvalidRect(r);
- END;
-
- INHERITED Resize(width, height, invalidate);
-
- IF (fIsActive | fDoFirstClick) & IsShown THEN
- gApplication.InvalidateCursorRgn;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MANonRes}
-
- PROCEDURE TWindow.ResizeByUser(globalMouse: Point);
-
- VAR
- growResult: LONGINT;
- resizeLimits: Rect;
-
- BEGIN
- IF fIsResizable THEN
- BEGIN
- resizeLimits := fResizeLimits; { GrowWindow may move SELF }
- growResult := GrowWindow(fWMgrWindow, globalMouse, resizeLimits);
- IF growResult <> 0 THEN
- Resize(LoWrd(growResult), HiWrd(growResult), kInvalidate);
- IF (fIsActive | fDoFirstClick) & IsShown THEN
- gApplication.InvalidateCursorRgn;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAOpen}
-
- PROCEDURE TWindow.SetResizeLimits(itsMinSize, itsMaxSize: Point);
-
- TYPE
- WStateDataPtr = ^WStateData;
- WStateDataHandle = ^WStateDataPtr;
-
- BEGIN
- fResizeLimits.topleft := itsMinSize;
- fResizeLimits.botRight := itsMaxSize;
-
- { If the window is zoomable, keep the window's state data current }
- IF BAND(fProcID, zoomDocProc) <> 0 THEN
- WITH WStateDataHandle(WindowPeek(fWMgrWindow)^.DataHandle)^^.stdState DO
- BEGIN
- right := Min(right, fLocation.h + itsMaxSize.h - 1);
- bottom := Min(bottom, fLocation.v + itsMaxSize.v - 1);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- PROCEDURE TWindow.SetTarget(newTarget: TEvtHandler);
-
- BEGIN
- IF newTarget = NIL THEN { Would be annoying if a nil got in here! }
- newTarget := SELF;
-
- fTarget := newTarget;
- IF gApplication.GetActiveWindow = SELF THEN
- gApplication.SetTarget(newTarget);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- PROCEDURE TWindow.SetTitle(newTitle: Str255);
-
- VAR
- oldTitle: Str255;
-
- BEGIN
- GetWTitle(fWMgrWindow, oldTitle); { to minimize flash, we only set the title
- if it's different from the current title }
- IF CompareStrings(oldTitle, newTitle) <> sortsEqual THEN
- SetWTitle(fWMgrWindow, newTitle);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAFile}
-
- PROCEDURE TWindow.SetTitleForDoc(newDocTitle: Str255);
-
- VAR
- title: Str255;
-
- BEGIN
- IF fPreDocname > 0 THEN { optimize for case of nothing to do }
- BEGIN
- GetTitle(title);
-
- IF SubstituteInTitle(title, newDocTitle, fPreDocname, fConstTitle) THEN
- SetTitle(title);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MANonRes}
-
- PROCEDURE TWindow.Show(state, redraw: BOOLEAN); OVERRIDE;
-
- BEGIN
- IF (fWMgrWindow <> NIL) & redraw THEN
- IF (fIsActive | fDoFirstClick) THEN
- gApplication.InvalidateCursorRgn;
- IF state THEN
- BEGIN
- WITH fWMgrWindow^.portRect DO
- Resize(right - left, bottom - top, redraw); { Be sure all views are sized right }
- ShowWindow(fWMgrWindow);
- END
- ELSE
- BEGIN
- HideWindow(fWMgrWindow);
- END;
-
- INHERITED Show(state, redraw);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAOpen}
-
- PROCEDURE TWindow.SimpleStagger(dh, dv: integer;
- VAR counter: integer);
-
- VAR
- globalRect: Rect; { The topLeft of the window must fall in
- here. }
- Pt: Point;
- nSlots: integer;
- slot: integer;
-
- BEGIN
- fStaggered := TRUE;
- { Get window rect, which gives us globalRect.topLeft & size of window }
- GetGlobalBounds(globalRect);
-
- { Compute globalRect.botRight = globalRect.topleft + <bounds botRight> - <window botRight> }
- Pt := globalRect.topleft;
- AddPt(fMoveBounds.botRight, Pt);
- SubPt(globalRect.botRight, Pt);
- globalRect.botRight := Pt;
-
- { This covers the case of dh & dv both >= 0; if either is less than
- 0, the right (bottom) limit is set to the left (top) edge of the
- screen -- allowing for some margin. This makes the right (bottom)
- edge less than the left (top) edge, but this is OK since the DIV
- statement below will be dividing 2 negative numbers. }
-
- IF dh < 0 THEN
- globalRect.right := fMoveBounds.left;
- IF dv < 0 THEN
- globalRect.bottom := fMoveBounds.top;
-
- { This code avoids divide by zero problems }
- IF (dh = 0) | (dv = 0) THEN
- nSlots := 0
- ELSE
- nSlots := Min((globalRect.right - globalRect.left + dh - 1) DIV dh, (globalRect.bottom -
- globalRect.top + dv - 1) DIV dv);
- IF nSlots = 0 THEN
- slot := 0
- ELSE
- slot := counter MOD nSlots;
-
- IF slot <> 0 THEN { move the window }
- BEGIN
- { pt ends up as the place to position the window }
- Pt := globalRect.topleft;
-
- Pt.h := Pt.h + (slot * dh);
- Pt.v := Pt.v + (slot * dv);
-
- Locate(Pt.h, Pt.v, kDontInvalidate);
- END;
-
- counter := counter + 1;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAWindowRes}
-
- PROCEDURE TWindow.Update; OVERRIDE;
-
- VAR
- fi: FailInfo;
-
- PROCEDURE HdlUpdate(error: OSErr;
- message: LONGINT);
-
- BEGIN
- EndUpdate(fWMgrWindow); { Need to balance the BeginUpdate }
- { Or we get into an infinite loop }
- { trying to update the window when }
- { displaying an alert }
- InvalidateFocus;
- END;
-
- BEGIN
- IF HasPendingUpdate THEN
- BEGIN
- InvalidateFocus;
- BeginUpdate(fWMgrWindow);
-
- CatchFailures(fi, HdlUpdate);
- DrawContents;
- Success(fi);
-
- EndUpdate(fWMgrWindow);
- InvalidateFocus;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MANonRes}
-
- PROCEDURE TWindow.Zoom(partCode: integer);
-
- VAR
- aGDScreenRect: Rect;
-
- PROCEDURE CalcZoomRect(forScreenRect: Rect);
-
- CONST
- edge = 2; { leave space around window structure area,
- ??? settable?}
-
- TYPE
- WStateDataPtr = ^WStateData;
- WStateDataHandle = ^WStateDataPtr;
-
- VAR
- zoomRect: Rect;
- width, height: integer;
-
- BEGIN
- InsetRect(forScreenRect, edge, edge);
- WITH forScreenRect DO
- BEGIN
- { calculate the maximum structure size }
- width := Min((right - left), fResizeLimits.botRight.h + fContDifference.h);
- height := Min((bottom - top), fResizeLimits.botRight.v + fContDifference.v);
-
- zoomRect.top := top + fContRgnInset.v + ((bottom - top) - height) DIV 2;
- zoomRect.left := left + fContRgnInset.h + ((right - left) - width) DIV 2;
- zoomRect.right := zoomRect.left + width - fContDifference.h - 1;
- zoomRect.bottom := zoomRect.top + height - fContDifference.v - 1;
-
- END;
-
- IF BAND(fProcID, zoomDocProc) <> 0 THEN
- WStateDataHandle(WindowPeek(fWMgrWindow)^.DataHandle)^^.stdState := zoomRect; { new
- zoom-out rect }
- END;
-
- BEGIN
- IF (qNeedsColorQD | gConfiguration.hasColorQD) & (partCode = inZoomOut) THEN { support multiple
- screens }
- BEGIN
- IF (GetMaxIntersectedDevice(aGDScreenRect) = NIL) THEN; { dont care about result }
- CalcZoomRect(aGDScreenRect);
- END;
-
- IF Focus THEN { ??? (still true?) The ROM has a bug
- requiring that thePort be the window being
- zoomed. }
- BEGIN
- EraseRect(thePort^.portRect); { Erasing was suggested by Ernie B.; the
- Finder does this. ??? is this _still_ a
- good idea. Help stamp out flicker. }
- ZoomWindow(fWMgrWindow, partCode, FALSE);
-
- { let the View know what we've done }
- WITH fWMgrWindow^.portRect DO
- Resize(right - left, bottom - top, kInvalidate);
- END;
-
- IF (fIsActive | fDoFirstClick) & IsShown THEN
- gApplication.InvalidateCursorRgn;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MANonRes}
-
- PROCEDURE TWindow.ZoomByUser(globalMouse: Point;
- partCode: integer);
-
- BEGIN
- IF TrackBox(fWMgrWindow, globalMouse, partCode) THEN
- Zoom(partCode);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S MAFields}
-
- PROCEDURE TWindow.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: integer)); OVERRIDE;
-
- VAR
- theFlag: BOOLEAN;
-
- BEGIN
- DoToField('TWindow', NIL, bClass);
- DoToField('fWMgrWindow', @fWMgrWindow, bWindowPtr);
- DoToField('fProcID', @fProcID, bInteger);
- DoToField('fMoveBounds', @fMoveBounds, bRect);
- DoToField('fResizeLimits', @fResizeLimits, bRect);
- DoToField('fTarget', @fTarget, bObject);
- DoToField('fTargetID', @fTargetID, bIDType);
- DoToField('fPreDocName', @fPreDocname, bInteger);
- DoToField('fConstTitle', @fConstTitle, bInteger);
- DoToField('fMustAdapt', @fMustAdapt, bBoolean);
- DoToField('fMustHorzCenter', @fMustHorzCenter, bBoolean);
- DoToField('fMustVertCenter', @fMustVertCenter, bBoolean);
- DoToField('fMustStagger', @fMustStagger, bBoolean);
- DoToField('fMustForceOnScreen', @fMustForceOnScreen, bBoolean);
- DoToField('fAdapted', @fAdapted, bBoolean);
- DoToField('fHorzCentered', @fHorzCentered, bBoolean);
- DoToField('fVertCentered', @fVertCentered, bBoolean);
- DoToField('fStaggered', @fStaggered, bBoolean);
- DoToField('fForcedOnScreen', @fForcedOnScreen, bBoolean);
- DoToField('fIsActive', @fIsActive, bBoolean);
- DoToField('fIsResizable', @fIsResizable, bBoolean);
- DoToField('fIsClosable', @fIsClosable, bBoolean);
- DoToField('fFreeOnClosing', @fFreeOnClosing, bBoolean);
- DoToField('fDisposeOnFree', @fDisposeOnFree, bBoolean);
- DoToField('fClosesDocument', @fClosesDocument, bBoolean);
- DoToField('fOpenInitially', @fOpenInitially, bBoolean);
- DoToField('fIsModal', @fIsModal, bBoolean);
- DoToField('fDoFirstClick', @fDoFirstClick, bBoolean);
- DoToField('fFloats', @fFloats, bBoolean);
- DoToField('fContRgnInset', @fContRgnInset, bPoint);
- DoToField('fContDifference', @fContDifference, bPoint);
- INHERITED Fields(DoToField);
- END;
-